package com.ruoyi.web.controller.ring.app;

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.bean.Builder;
import com.ruoyi.ring.domain.*;
import com.ruoyi.ring.domain.dto.*;
import com.ruoyi.ring.domain.vo.*;
import com.ruoyi.ring.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 身体状况 （APP）
 */
@Slf4j
@RestController
@RequestMapping("/ring/app/physical_condition")
public class AppPhysicalConditionController extends BaseController
{
    @Resource
    private IRingPhysicalConditionService ringPhysicalConditionService;
    @Resource
    private IRingTodaySignService ringTodaySignService;
    @Resource
    private IUserFoodInfoService userFoodInfoService;
    @Resource
    private IDailyTagsService dailyTagsService;
    @Resource
    private IDailyTagsConfService dailyTagsConfService;
    @Resource
    private IRingSleepDetailService ringSleepDetailService;
    /**
     * 身体状况生成今日签-app
     */
    @Log(title = "生成今日签", businessType = BusinessType.INSERT)
    @PostMapping("/add-today-sign ")
    public AjaxResult addTodaySign(@RequestBody RingTodaySignDTO ringTodaySignDTO)
    {
        RingTodaySign ringTodaySign = ringPhysicalConditionService.addTodaySign(ringTodaySignDTO);
        if(ringTodaySign != null){
            return AjaxResult.success(ringTodaySign);
        }else {
            return AjaxResult.error("生成今日签失败！");
        }
    }

    /**
     * 身体状况今日签列表-app
     */
    @GetMapping("/query-ring-today-sign-list")
    public AjaxResult queryRingTodaySignList(PhysicalConditionDTO physicalConditionDTO)
    {
        long userId = SecurityUtils.getUserId();
        log.info("身体状况今日签列表: userId={}, param={}", userId, JSON.toJSONString(physicalConditionDTO));
        physicalConditionDTO.setUserId(userId);
        return AjaxResult.success(ringTodaySignService.queryRingTodaySignList(physicalConditionDTO));
    }

    /**
     * 身体状况今日签详细信息-app
     */
    @GetMapping(value = "/query-ring-today-sgn/{id}")
    public AjaxResult getRingTodaySignInfo(@PathVariable("id") Long id)
    {
        return AjaxResult.success(ringTodaySignService.selectRingTodaySignById(id));
    }
    /**
     *  身体状况评分-app
     */
    @GetMapping(value = "/query-condition-score")
    public AjaxResult queryConditionScore(PhysicalConditionDTO physicalConditionDTO)
    {
        long userId = SecurityUtils.getUserId();
        log.info("身体状况评分: userId={}, param={}", userId, JSON.toJSONString(physicalConditionDTO));
        physicalConditionDTO.setUserId(userId);
        return AjaxResult.success(ringPhysicalConditionService.queryConditionScore(physicalConditionDTO));
    }

    /**
     * 身体状况生命关键指标看板-app
     */
    @GetMapping(value = "/query-dashboard-metrics")
    public AjaxResult queryDashboardMetrics(PhysicalConditionDTO physicalConditionDTO)
    {
        long userId = SecurityUtils.getUserId();
        log.info("身体状况生命关键指标看板: userId={}, param={}", userId, JSON.toJSONString(physicalConditionDTO));
        physicalConditionDTO.setUserId(userId);
        return AjaxResult.success(ringPhysicalConditionService.queryDashboardMetrics(physicalConditionDTO));
    }

    /**
     * 身体状况上报饮食记录-app
     */
    @Log(title = "饮食记录", businessType = BusinessType.INSERT)
    @PostMapping("/add-food-info")
    public AjaxResult addFoodInfo(UserFoodInfoDTO userFoodInfoDTO)
    {
        UserFoodInfo userFoodInfo = ringPhysicalConditionService.addFoodInfo(userFoodInfoDTO);
        if(userFoodInfo != null){
            return AjaxResult.success(userFoodInfo);
        }else {
            return AjaxResult.error("报饮食记录失败！");
        }
    }
    /**
     * 身体状况查询饮食记录列表5条-app
     */
    @GetMapping("/query-user-food-info-list")
    public AjaxResult queryUserFoodInfoList(PhysicalConditionDTO physicalConditionDTO)
    {
        long userId = SecurityUtils.getUserId();
        log.info("身体状况查询饮食记录列表5条: userId={}, param={}", userId, JSON.toJSONString(physicalConditionDTO));
        List<UserFoodInfo> list = userFoodInfoService.queryUserFoodList(Builder.of(GeneralSecondDTO::new).
                with(GeneralSecondDTO::setUserId, userId).
                with(GeneralSecondDTO::setRecordDate, physicalConditionDTO.getDailyValue()).
                with(GeneralSecondDTO::setType, "1")
                .build()).stream().limit(5).collect(Collectors.toList());
        return AjaxResult.success(list);
    }

    /**
     * 身体状况上报情绪状态-app
     */
    @Log(title = "压力情绪信息", businessType = BusinessType.INSERT)
    @PostMapping("/add-emotional-info-state")
    public AjaxResult addEmotionalInfoState(@RequestBody RingEmotionalInfoStateDTO emotionalInfoStateDTO)
    {
        RingEmotionalInfo ringEmotionalInfo = ringPhysicalConditionService.addEmotionalInfoState(emotionalInfoStateDTO);
        if(ringEmotionalInfo != null){
            return AjaxResult.success(ringEmotionalInfo);
        }else {
            return AjaxResult.error("上报情绪状态失败！");
        }
    }

    /**
     * 身体状况查询压力情绪和压力信息-app
     */
    @GetMapping("/query-emotional-info-state")
    public AjaxResult queryEmotionalInfoOrState(PhysicalConditionDTO physicalConditionDTO)
    {
        long userId = SecurityUtils.getUserId();
        log.info("身体状况查询压力情绪和压力信息: userId={}, param={}", userId, JSON.toJSONString(physicalConditionDTO));
        physicalConditionDTO.setUserId(userId);
        return AjaxResult.success(ringPhysicalConditionService.queryEmotionalInfoOrState(physicalConditionDTO));
    }


    /**
     * 身体状况上报事件小计-app
     */
    @Log(title = "身体状况上报事件小计", businessType = BusinessType.INSERT)
    @PostMapping("/add-daily-tag")
    public AjaxResult addDailyTag(@RequestBody DailyTagsDTO dailyTagsDTO)
    {
        DailyTags dailyTags = Convert.convert(DailyTags.class,dailyTagsDTO);
        dailyTags.setUserId(SecurityUtils.getUserId());
        DailyTags tags = ringPhysicalConditionService.addDailyTag(dailyTags);
        if(tags != null){
            return AjaxResult.success(tags);
        }else {
            return AjaxResult.error("上报事件小计失败！");
        }
    }
    /**
     * 身体状况修改事件小计评分-app
     */
    @Log(title = "修改事件小计评分", businessType = BusinessType.UPDATE)
    @PostMapping("/upd-daily-tag")
    public AjaxResult updDailyTags(@RequestBody DailyTags dailyTags)
    {
        return toAjax(dailyTagsService.updateDailyTags(dailyTags));
    }
    /**
     * 身体状况显示事件小计-app
     */
    @GetMapping("/query-daily-tags-list")
    public AjaxResult queryDailyTagsList(DailyTagsQueryDTO dailyTagsQueryDTO)
    {
        long userId = SecurityUtils.getUserId();
        log.info("身体状况显示事件小计: userId={}, param={}", userId, JSON.toJSONString(dailyTagsQueryDTO));
        DailyTags dailyTags = Convert.convert(DailyTags.class,dailyTagsQueryDTO);
        dailyTags.setUserId(userId);
        return AjaxResult.success(dailyTagsService.queryDailyTagsList(dailyTags));
    }
    /**
     * 身体状况按标签类型分组列表-app
     */
    @GetMapping("/query--daily-tags-conf-list")
    public AjaxResult queryDailyTagsConfList()
    {
        List<TagTypeGroupVO> list = dailyTagsConfService.queryList(Builder.of(DailyTagsConf::new).with(DailyTagsConf::setUserId, SecurityUtils.getUserId()).build());
        return AjaxResult.success(list);
    }
    /**
     * 身体状况获取某一类型对应标签集合-app
     */
    @GetMapping(value = "/query-daily-tag-conf")
    public AjaxResult queryDailyTagsConf(DailyTagsConfDTO dailyTagsConfDTO)
    {
        long userId = SecurityUtils.getUserId();
        log.info("身体状况获取某一类型对应标签集合: userId={}, param={}", userId, JSON.toJSONString(dailyTagsConfDTO));
        DailyTagsConf dailyTagsConf = Convert.convert(DailyTagsConf.class,dailyTagsConfDTO);
        dailyTagsConf.setUserId(userId);
        List<DailyTagsConfVO> list = dailyTagsConfService.queryOneDailyTagsConf(dailyTagsConf);
        return AjaxResult.success(list);
    }
    /**
     * 身体状况上报事件小计内容-app
     */
    @Log(title = "身体状况上报事件小计内容", businessType = BusinessType.INSERT)
    @PostMapping("/add-daily-tag-conf")
    public AjaxResult addDailyTagsConf(@RequestBody DailyTagsConf dailyTagsConf) {
        dailyTagsConf.setDailyValue(DateUtils.dateTime(DateUtils.YYYY_MM_DD, DateUtils.getDate()));
        return toAjax(dailyTagsConfService.insertDailyTagsConf(dailyTagsConf));
    }

    /**
     * 身体状况心率信息-app
     */
    @GetMapping("/query-heart-rate-info")
    public AjaxResult queryHeartRateInfo(RingHeartRateInfoDTO heartRateInfoDTO)
    {
        long userId = SecurityUtils.getUserId();
        log.info("身体状况心率信息: userId={}, param={}", userId, JSON.toJSONString(heartRateInfoDTO));
        RingHeartRateInfoVO heartRateInfoVO = ringPhysicalConditionService.queryHeartRateInfo(heartRateInfoDTO);
        return AjaxResult.success(heartRateInfoVO);
    }
    /**
     * 身体状况心率变异性信息-app
     */
    @GetMapping("/query-ring_hrv-info")
    public AjaxResult queryRingHrvInfo(RingHrvInfoDTO ringHrvInfoDTO)
    {
        long userId = SecurityUtils.getUserId();
        log.info("身体状况心率变异性信息: userId={}, param={}", userId, JSON.toJSONString(ringHrvInfoDTO));
        RingHrvInfoVO ringHrvInfoVO = ringPhysicalConditionService.queryRingHrvInfo(ringHrvInfoDTO);
        return AjaxResult.success(ringHrvInfoVO);
    }
    /**
     * 身体状况睡眠内容详情-app
     */
    @GetMapping("/query-info")
    public AjaxResult queryInfo(RingSleepDetailInfoDTO sleepDetailInfoDTO){
        long userId = SecurityUtils.getUserId();
        log.info("身体状况睡眠内容详情: userId={}, param={}", userId, JSON.toJSONString(sleepDetailInfoDTO));
        return AjaxResult.success(ringSleepDetailService.queryDayInfo(sleepDetailInfoDTO));
    }
    /**
     * 身体状况血氧饱和度-app
     */
    @GetMapping("/query-sleep-blood-oxygen")
    public AjaxResult querySleepBloodOxygen(RingSleepDetailInfoDTO sleepDetailInfoDTO){
        long userId = SecurityUtils.getUserId();
        log.info("身体状况血氧饱和度: userId={}, param={}", userId, JSON.toJSONString(sleepDetailInfoDTO));
        return AjaxResult.success(ringPhysicalConditionService.querySleepBloodOxygen(sleepDetailInfoDTO));
    }
    /**
     * 身体状况活动-app
     */
    @GetMapping("/query-physical-ctivities")
    public AjaxResult queryPhysicalActivities(PhysicalConditionDTO physicalConditionDTO){
        long userId = SecurityUtils.getUserId();
        log.info("身体状况活动: userId={}, param={}", userId, JSON.toJSONString(physicalConditionDTO));
        physicalConditionDTO.setUserId(userId);
        PhysicalActivitiesVO physicalActivitiesVO = ringPhysicalConditionService.queryPhysicalActivities(physicalConditionDTO);
        return AjaxResult.success(physicalActivitiesVO);
    }
    /**
     * 身体状况锻炼记录-app
     */
    @GetMapping("/query-exercise_records")
    public AjaxResult queryExerciseRecords(PhysicalConditionDTO physicalConditionDTO){
        long userId = SecurityUtils.getUserId();
        log.info("身体状况锻炼记录: userId={}, param={}", userId, JSON.toJSONString(physicalConditionDTO));
        physicalConditionDTO.setUserId(userId);
        ExerciseRecordsVO exerciseRecordsVO = ringPhysicalConditionService.queryExerciseRecords(physicalConditionDTO);
        return AjaxResult.success(exerciseRecordsVO);
    }

    /**
     * 生理周期-app
     */
    @GetMapping("/query-menstrual-cycle")
    public AjaxResult queryMenstrualCycle(PhysicalConditionDTO physicalConditionDTO){
        long userId = SecurityUtils.getUserId();
        log.info("生理周期: userId={}, param={}", userId, JSON.toJSONString(physicalConditionDTO));
        physicalConditionDTO.setUserId(userId);
        MenstrualCycleVO menstrualCycleVO = ringPhysicalConditionService.queryMenstrualCycle(physicalConditionDTO);
        return AjaxResult.success(menstrualCycleVO);
    }
}
